﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace Rhino_Mocks.Utilities {
    /// <summary>
    /// 生成静态文件
    /// </summary>
    public class StaticFileResultFilterAttribute : FilterAttribute, IResultFilter {
        public void OnResultExecuted(ResultExecutedContext filterContext)
        {
            
        }

        public void OnResultExecuting(ResultExecutingContext filterContext)
        {
            if (!filterContext.HttpContext.Response.IsRequestBeingRedirected)
            {
                string basePath = "~/ViewsStatic";   //根路径
                string path = string.Format("{0}/{1}/{2}", basePath, filterContext.RouteData.Values["controller"], filterContext.RouteData.Values["action"]);//控制器路径
                string filePath = null;//文件路径
                bool isNeedCreate = false;//要当前生成缓存文件
                bool isNeedStatic = false;//确定要调静态文件
                var viewResult = filterContext.Result as ViewResult;
                object Model = viewResult.Model;

                if (!Directory.Exists(filterContext.HttpContext.Server.MapPath(path)))
                    Directory.CreateDirectory(filterContext.HttpContext.Server.MapPath(path));
                if (Model != null)
                {
                    isNeedStatic = true;
                    //设定文件路径
                    filePath = string.Format("{0}/{1}.html", path, filterContext.RouteData.Values["id"].ToString());
                    filePath = filterContext.HttpContext.Server.MapPath(filePath);
                    if (!File.Exists(filePath)) isNeedCreate = true;
                    else if (File.Exists(filePath))
                    {
                        FileInfo fileInfo = new FileInfo(filePath);
                        if (DateTime.Now - fileInfo.LastWriteTime >= new TimeSpan(3, 0, 0, 0))
                            isNeedCreate = true;
                        else if (fileInfo.Length == 0)
                            isNeedCreate = true;

                        fileInfo = null;
                    }
                }


                #region 生成静态文件

                if (isNeedCreate)
                {
                    isNeedStatic = CreateStaticHtmlFile(filterContext, filePath, isNeedStatic, viewResult);
                }

                #endregion

                #region 调取静态文件
                if (isNeedStatic)
                {
                    filterContext.HttpContext.Response.Clear();
                    filterContext.HttpContext.Response.TransmitFile(filePath);
                    filterContext.HttpContext.Response.Flush();
                    filterContext.HttpContext.Response.End();
                    filterContext.Cancel = true;
                }
                #endregion
            }
        }

        private bool CreateStaticHtmlFile(ResultExecutingContext filterContext, string filePath, bool isNeedStatic, ViewResult viewResult)
        {
            FileInfo fileInfo = null;
            FileStream fileStream = null;
            StreamWriter streamWriter = null;
            try
            {
                //生成静态页面
                fileInfo = new FileInfo(filePath);
                fileStream = new FileStream(fileInfo.FullName, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None);
                streamWriter = new StreamWriter(fileStream);
                if (viewResult.View == null)
                {
                    viewResult.ExecuteResult(filterContext.Controller.ControllerContext);
                }
                var viewContext = new ViewContext(filterContext.Controller.ControllerContext, viewResult.View, viewResult.ViewData, viewResult.TempData, streamWriter);
                viewResult.View.Render(viewContext, streamWriter);
            }
            catch (Exception ex)
            {
                isNeedStatic = false;
            }
            finally
            {
                if (streamWriter != null)
                {
                    streamWriter.Close();
                    streamWriter.Dispose();
                    streamWriter = null;
                }
                if (fileStream != null)
                {
                    fileStream.Close();
                    fileStream.Dispose();
                    fileStream = null;
                }

                if (fileInfo != null)
                {
                    fileInfo = null;
                }

            }
            return isNeedStatic;
        }
    }
}